﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Drawing;
using System.Web.UI.HtmlControls;
using DataTablesInteractions;

namespace SEP.ServerControls
{
    [DefaultProperty("Text")]
    [ToolboxData("<{0}:JQueryDataTable runat=server></{0}:JQueryDataTable>")]
    [ToolboxBitmap(typeof(ResourceFinder), "SEP.server_controls.DataTable_Control.JQueryDataTable.bmp")]

    public class JQueryDataTable : Label
    {
        private List<BusinessLogic.Table> _TableData;
        [Browsable(false)] //seeing this in the Properties window would not make sense
        public virtual List<BusinessLogic.Table> TableData
        {
            get { return _TableData; }
            set { _TableData = value; }
        }

        private string _SqlToExecute = "";
        [
          Browsable(true)
         , Category("Data Source")
         , Description("The SQL string whose results should be rendered as a DataTable")
        ]
        public virtual string SqlToExecute
        {
            get { return _SqlToExecute; }
            set { _SqlToExecute = value; }
        }

        private string _ConnString = "";
        [
          Browsable(true)
         , Category("Connection string")
         , Description("The connection string from the web.config file")
        ]
        public string ConnectionString
        {
            get { return _ConnString; }
            set { _ConnString = value; }
        }

        //not implemented yet
        public Boolean AllowAdd;
        public Boolean AllowEdit;
        public Boolean AllowDelete;

        protected override void OnPreRender(EventArgs e)
        {
            //Page.ClientScript.RegisterClientScriptInclude(this.GetType(), "MaskedJavaScript", "test.js");
            base.OnPreRender(e);
        }

        protected override void RenderContents(HtmlTextWriter writer)
        {
            string columnsJson = "";
            string dataJson = "";

            //take whatever query the caller gave us
            if (!string.IsNullOrEmpty(ConnectionString))
            {
                DatabaseWrapper dbw = new DatabaseWrapper(ConnectionString, SqlToExecute, System.Data.CommandType.Text);
                JsonDataManager jsonMgr = new JsonDataManager(dbw.ExecuteDataTable());

                columnsJson = jsonMgr.ColumnHeadersAsJson();
                dataJson = jsonMgr.DataAsJson();
            }
            else if (TableData != null)
            {
                JsonDataManager jsonMgr = new JsonDataManager(TableData);
                columnsJson = jsonMgr.ColumnHeadersAsJson();
                dataJson = jsonMgr.DataAsJson();
            }
            /*
            DataTables needs two things to work properly:
            1 - Column headers
            2 - Data

            Both have to be encoded as JSON objects.
            Both are actually bound to the grid from Javascript code.

            So we do this:
            1 - Run our query
            2 - Grab the column headers from the result
            3 - Grab the data from the result
            4 - Encode #s 2 and 3 as JSON objects with JsonConvert (an external library)
            5 - Push those JSON values into the Javascript code directly
            */
            StringBuilder sbJavascript = new StringBuilder();
            sbJavascript.Append(@"    <script type=""text/javascript"">");
            sbJavascript.Append(@"        $(document).ready(function () {");
            sbJavascript.Append(@"            $('#dynamic').html('<table cellpadding=""0"" cellspacing=""0"" border=""0"" class=""display"" id=""results_table""></table>');");
            sbJavascript.Append(@"            /*grab the column headers from where c# code left it, convert to a real JSON object (not a string)*/");
            sbJavascript.Append(@"            jsonstring_ColumnHeadersFromCSharp = '" + columnsJson + "';");
            sbJavascript.Append(@"            jsonColumnHeaders = jQuery.parseJSON(jsonstring_ColumnHeadersFromCSharp);");
            sbJavascript.Append(@"");
            sbJavascript.Append(@"            $('#results_table').dataTable(");
            sbJavascript.Append(@"              { ""aaData"": null, ""aoColumns"": jsonColumnHeaders }");
            sbJavascript.Append(@"            );");
            sbJavascript.Append(@"        });");
            sbJavascript.Append(@"");
            sbJavascript.Append(@"        /*when the user clicks a link, refresh the grid from query results*/");
            sbJavascript.Append(@"        $(""#divRefresh"").click(function () {");
            sbJavascript.Append(@"            RefreshGridFromQueryResults();");
            sbJavascript.Append(@"        });");
            sbJavascript.Append(@"");
            sbJavascript.Append(@"        $(""#divClear"").click(function () {");
            sbJavascript.Append(@"            ClearGrid();");
            sbJavascript.Append(@"        });");
            sbJavascript.Append(@"");
            sbJavascript.Append(@"        function RefreshGridFromQueryResults() {");
            sbJavascript.Append(@"            /*wipe out whatever was there before*/");
            sbJavascript.Append(@"            ClearGrid();");
            sbJavascript.Append(@"            /*grab the actual data from where c# code left it, convert to a real JSON object (not a string)*/");
            sbJavascript.Append(@"            jsonstring_DataFromCSharp = '" + dataJson + "';");
            sbJavascript.Append(@"            jsonDataSource = jQuery.parseJSON(jsonstring_DataFromCSharp);");
            sbJavascript.Append(@"");
            sbJavascript.Append(@"            /*add my query result into the grid*/");
            sbJavascript.Append(@"            if (jsonDataSource != null) {");
            sbJavascript.Append(@"                $('#results_table').dataTable().fnAddData(jsonDataSource);");
            sbJavascript.Append(@"            }");
            sbJavascript.Append(@"            else {");
            sbJavascript.Append(@"                alert(""json object was null"");");
            sbJavascript.Append(@"            }");
            sbJavascript.Append(@"        }");
            sbJavascript.Append(@"");
            sbJavascript.Append(@"        function ClearGrid() {");
            sbJavascript.Append(@"            /*wipe out whatever was there before*/");
            sbJavascript.Append(@"            $('#results_table').dataTable().fnClearTable();");
            sbJavascript.Append(@"        }");
            sbJavascript.Append(@"    </script>");

            StringBuilder sbHTML = new StringBuilder();
            sbHTML.Append(@"<head runat=""server"">");
            sbHTML.Append(@"    <script type=""text/javascript"" charset=""utf-8"" src=""/DataTables/media/js/jquery.js""></script>");
            sbHTML.Append(@"    <script type=""text/javascript"" charset=""utf-8"" src=""/DataTables/media/js/jquery.dataTables.js""></script>");
            sbHTML.Append(@"    <style type=""text/css"" title=""currentStyle"">");
            sbHTML.Append(@"        @import ""/DataTables/media/css/demo_table.css"";");
            sbHTML.Append(@"    </style>");
            sbHTML.Append(@"    <title></title>");
            sbHTML.Append(@"</head>");
            sbHTML.Append(@"<body>");
            sbHTML.Append(@"    <div id=""divRefresh"">");
            sbHTML.Append(@"      <asp:HyperLink ID=""hlkGridRefresh"" runat=""server"" BackColor=""#CCFFFF"" BorderStyle=""Double"" ForeColor=""#003300"" ");
            sbHTML.Append(@"            Font-Bold=""True"">Refresh the grid</asp:HyperLink>");
            sbHTML.Append(@"    </div>");
            sbHTML.Append(@"    <div id=""divClear"">");
            sbHTML.Append(@"      <asp:HyperLink ID=""hlkGridClear"" runat=""server"" BackColor=""Black"" BorderStyle=""Double"" ForeColor=""White"" Font-Bold=""True"">Clear the grid</asp:HyperLink>");
            sbHTML.Append(@"    </div>");
            sbHTML.Append(@"");
            sbHTML.Append(@"    <form id=""form1"" runat=""server"">");
            sbHTML.Append(@"    <div>");
            sbHTML.Append(@"        <!--");
            sbHTML.Append(@"        This table will hold our data.");
            sbHTML.Append(@"        It just has to be declared - DataTables will do the rest later");
            sbHTML.Append(@"        -->");
            sbHTML.Append(@"        <table cellpadding=""0"" cellspacing=""0"" border=""0"" class=""display"" id=""results_table"" width=""100%"">");
            sbHTML.Append(@"        </table>");
            sbHTML.Append(@"    </div>");

            sbHTML.Append(sbJavascript.ToString());
            sbHTML.Append(@"</body>");
            writer.Write(sbHTML.ToString());
        }
    }
}